#include "SMPPSession.hpp"

using namespace smpp::session;
using namespace smpp::constants::CommandId;

Request::Request(const Bind &nBind,int nResponseTime):
_Request(reinterpret_cast<void *>(new Bind(nBind))){
	startTimer(nResponseTime);
}

Request::Request(const Unbind &nUnbind,int nResponseTime):
_Request(reinterpret_cast<void *>(new Unbind(nUnbind))){
	startTimer(nResponseTime);
}

Request::Request(const EnquireLink &nEnquireLink,int nResponseTime):
_Request(reinterpret_cast<void *>(new EnquireLink(nEnquireLink))){
	startTimer(nResponseTime);
}

Request::Request(const SubmitSM &nSubmitSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new SubmitSM(nSubmitSM))){
	startTimer(nResponseTime);
}

Request::Request(const DataSM &nDataSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new DataSM(nDataSM))){
	startTimer(nResponseTime);
}

Request::Request(const SubmitMulti &nSubmitMulti,int nResponseTime):
_Request(reinterpret_cast<void *>(new SubmitMulti(nSubmitMulti))){
	startTimer(nResponseTime);
}

Request::Request(const DeliverSM &nDeliverSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new DeliverSM(nDeliverSM))){
	startTimer(nResponseTime);
}

Request::Request(const BroadcastSM &nBroadcastSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new BroadcastSM(nBroadcastSM))){
	startTimer(nResponseTime);
}

Request::Request(const CancelSM &nCancelSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new CancelSM(nCancelSM))){
	startTimer(nResponseTime);
}

Request::Request(const QuerySM &nQuerySM,int nResponseTime):
_Request(reinterpret_cast<void *>(new QuerySM(nQuerySM))){
	startTimer(nResponseTime);
}

Request::Request(const ReplaceSM &nReplaceSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new ReplaceSM(nReplaceSM))){
	startTimer(nResponseTime);
}

Request::Request(const QueryBroadcastSM &nQueryBroadcastSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new QueryBroadcastSM(nQueryBroadcastSM))){
	startTimer(nResponseTime);
}

Request::Request(const CancelBroadcastSM &nCancelBroadcastSM,int nResponseTime):
_Request(reinterpret_cast<void *>(new CancelBroadcastSM(nCancelBroadcastSM))){
	startTimer(nResponseTime);
}

Request::~Request(){
	Header *_Header(reinterpret_cast<Header *>(_Request));
	switch(_Header->getCommandId()){
		case CM_BIND_TRANSMITTER:
			delete reinterpret_cast<Bind *>(_Request);
			break;
		case CM_BIND_RECEIVER:
			delete reinterpret_cast<Bind *>(_Request);
			break;
		case CM_BIND_TRANSCEIVER:
			delete reinterpret_cast<Bind *>(_Request);
			break;
		case CM_UNBIND:
			delete reinterpret_cast<Unbind *>(_Request);
			break;
		case CM_ENQUIRE_LINK:
			delete reinterpret_cast<EnquireLink *>(_Request);
			break;
		case CM_SUBMIT_SM:
			delete reinterpret_cast<SubmitSM *>(_Request);
			break;
		case CM_DATA_SM:
			delete reinterpret_cast<DataSM *>(_Request);
			break;
		case CM_SUBMIT_MULTI:
			delete reinterpret_cast<SubmitMulti *>(_Request);
			break;
		case CM_DELIVER_SM:
			delete reinterpret_cast<DeliverSM *>(_Request);
			break;
		case CM_BROADCAST_SM:
			delete reinterpret_cast<BroadcastSM *>(_Request);
			break;
		case CM_CANCEL_SM:
			delete reinterpret_cast<CancelSM *>(_Request);
			break;
		case CM_QUERY_SM:
			delete reinterpret_cast<QuerySM *>(_Request);
			break;
		case CM_REPLACE_SM:
			delete reinterpret_cast<ReplaceSM *>(_Request);
			break;
		case CM_QUERY_BROADCAST_SM:
			delete reinterpret_cast<QueryBroadcastSM *>(_Request);
			break;
		case CM_CANCEL_BROADCAST_SM:
			delete reinterpret_cast<CancelBroadcastSM *>(_Request);
			break;
	}
}

bool Request::operator ==(const Header &nHeader) const{
	Header *_Header(reinterpret_cast<Header *>(_Request));
	if(nHeader.getSequenceNumber() == _Header->getSequenceNumber())
		switch(_Header->getCommandId()){
			case CM_BIND_TRANSMITTER:
				if(	nHeader.getCommandId() == CM_BIND_TRANSMITTER_RESP || 
					nHeader.getCommandId() == CM_BIND_TRANSMITTER)
					return true;
				break;
			case CM_BIND_RECEIVER:
				if(	nHeader.getCommandId() == CM_BIND_RECEIVER_RESP || 
					nHeader.getCommandId() == CM_BIND_RECEIVER)
					return true;
				break;
			case CM_BIND_TRANSCEIVER:
				if(	nHeader.getCommandId() == CM_BIND_TRANSCEIVER_RESP || 
					nHeader.getCommandId() == CM_BIND_TRANSCEIVER)
					return true;
				break;
			case CM_UNBIND:
				if(	nHeader.getCommandId() == CM_UNBIND_RESP || 
					nHeader.getCommandId() == CM_UNBIND)
					return true;
				break;
			case CM_ENQUIRE_LINK:
				if(	nHeader.getCommandId() == CM_ENQUIRE_LINK_RESP || 
					nHeader.getCommandId() == CM_ENQUIRE_LINK)
					return true;
				break;
			case CM_SUBMIT_SM:
				if(	nHeader.getCommandId() == CM_SUBMIT_SM_RESP || 
					nHeader.getCommandId() == CM_SUBMIT_SM)
					return true;
				break;
			case CM_DATA_SM:
				if(	nHeader.getCommandId() == CM_DATA_SM_RESP || 
					nHeader.getCommandId() == CM_DATA_SM)
					return true;
				break;
			case CM_SUBMIT_MULTI:
				if(	nHeader.getCommandId() == CM_SUBMIT_MULTI_RESP || 
					nHeader.getCommandId() == CM_SUBMIT_MULTI)
					return true;
				break;
			case CM_DELIVER_SM:
				if(	nHeader.getCommandId() == CM_DELIVER_SM_RESP || 
					nHeader.getCommandId() == CM_DELIVER_SM)
					return true;
				break;
			case CM_BROADCAST_SM:
				if(	nHeader.getCommandId() == CM_BROADCAST_SM_RESP || 
					nHeader.getCommandId() == CM_BROADCAST_SM)
					return true;
				break;
			case CM_CANCEL_SM:
				if(	nHeader.getCommandId() == CM_CANCEL_SM_RESP || 
					nHeader.getCommandId() == CM_CANCEL_SM)
					return true;
				break;
			case CM_QUERY_SM:
				if(	nHeader.getCommandId() == CM_QUERY_SM_RESP || 
					nHeader.getCommandId() == CM_QUERY_SM)
					return true;
				break;
			case CM_REPLACE_SM:
				if(	nHeader.getCommandId() == CM_REPLACE_SM_RESP || 
					nHeader.getCommandId() == CM_REPLACE_SM)
					return true;
				break;
			case CM_QUERY_BROADCAST_SM:
				if( nHeader.getCommandId() == CM_QUERY_BROADCAST_SM_RESP || 
					nHeader.getCommandId() == CM_QUERY_BROADCAST_SM)
					return true;
				break;
			case CM_CANCEL_BROADCAST_SM:
				if( nHeader.getCommandId() == CM_CANCEL_BROADCAST_SM_RESP || 
					nHeader.getCommandId() == CM_CANCEL_BROADCAST_SM)
					return true;
				break;
		}
	return false;
}

void Request::timerEvent(QTimerEvent *nEvent){
	Header *_Header(reinterpret_cast<Header *>(_Request));
	switch(_Header->getCommandId()){
	case CM_BIND_TRANSMITTER:
		emit onBindTransmitterTimeout(*reinterpret_cast<Bind *>(_Request));
		break;
	case CM_BIND_RECEIVER:
		emit onBindReceiverTimeout(*reinterpret_cast<Bind *>(_Request));
		break;
	case CM_BIND_TRANSCEIVER:
		emit onBindTransceiverTimeout(*reinterpret_cast<Bind *>(_Request));
		break;
	case CM_UNBIND:
		emit onUnbindTimeout(*reinterpret_cast<Unbind *>(_Request));
		break;
	case CM_ENQUIRE_LINK:
		emit onEnquireLinkTimeout(*reinterpret_cast<EnquireLink *>(_Request));
		break;
	case CM_SUBMIT_SM:
		emit onSubmitSMTimeout(*reinterpret_cast<SubmitSM *>(_Request));
		break;
	case CM_DATA_SM:
		emit onDataSMTimeout(*reinterpret_cast<DataSM *>(_Request));
		break;
	case CM_SUBMIT_MULTI:
		emit onSubmitMultiTimeout(*reinterpret_cast<SubmitMulti *>(_Request));
		break;
	case CM_DELIVER_SM:
		emit onDeliverSMTimeout(*reinterpret_cast<DeliverSM *>(_Request));
		break;
	case CM_BROADCAST_SM:
		emit onBroadcastSMTimeout(*reinterpret_cast<BroadcastSM *>(_Request));
		break;
	case CM_CANCEL_SM:
		emit onCancelSMTimeout(*reinterpret_cast<CancelSM *>(_Request));
		break;
	case CM_QUERY_SM:
		emit onQuerySMTimeout(*reinterpret_cast<QuerySM *>(_Request));
		break;
	case CM_REPLACE_SM:
		emit onReplaceSMTimeout(*reinterpret_cast<ReplaceSM *>(_Request));
		break;
	case CM_QUERY_BROADCAST_SM:
		emit onQueryBroadcastSMTimeout(*reinterpret_cast<QueryBroadcastSM *>(_Request));
		break;
	case CM_CANCEL_BROADCAST_SM:
		emit onCancelBroadcastSMTimeout(*reinterpret_cast<CancelBroadcastSM *>(_Request));
		break;
	}
}

Session::Session(
int sessionInitTime,
int enquireLinkTime,
int inactivityTime,
int responseTime,
const QHostAddress &host,
quint16 port):
_Host(host),
_Port(port),
_State(Closed),
_UseSsl(false),
_UseProxy(false),
_SessionInitTimerId(-1),
_EnquireLinkTimerId(-1),
_InactivityTimerId(-1),
_SessionInitTime(sessionInitTime),
_EnquireLinkTime(enquireLinkTime),
_InactivityTime(inactivityTime),
_ResponseTime(responseTime){
	_UseEncoder.fetchAndAddOrdered(1);
	_UseDecoder.fetchAndAddOrdered(1);
	_UseRequestList.fetchAndAddOrdered(1);
	connect(&_Socket, SIGNAL(error(QAbstractSocket::SocketError)),
			SLOT(_SocketError(QAbstractSocket::SocketError)));
	connect(&_Socket, SIGNAL(readyRead()), SLOT(_DecodePdu()));
	connect(&_Socket, SIGNAL(connected()), SLOT(_OpenResp()));
	connect(&_Socket, SIGNAL(disconnected()), SLOT(_CloseResp()));
}

void Session::setSocketDescriptor(int nSocketDescriptor){
	_Socket.setSocketDescriptor(nSocketDescriptor);
}

void Session::_Open(){
	if(_Socket.state() != QTcpSocket::ConnectedState)
		if(_UseSsl)
			_Socket.connectToHostEncrypted(	_Host.toString(),
			_Port,QIODevice::ReadWrite);	
		else
			_Socket.connectToHost(_Host,_Port,QIODevice::ReadWrite);
}

void Session::_Close(){
	if(_Socket.state() == QTcpSocket::ConnectedState){
		_Socket.close();
		_Socket.disconnectFromHost();
	}
}

void Session::_SendPdu(){
	if(	_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX)
		killTimer(_InactivityTimerId);
	if ( _Socket.state() == QTcpSocket::ConnectedState && _Socket.isValid() ){
		_Socket.flush();
		_Socket.write(_Encoder.getMassive());
	}
	_Encoder.clearMassive();
	_UseEncoder.fetchAndAddOrdered(1);
	if(	_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX)
		_InactivityTimerId = startTimer(_InactivityTime);
}

void Session::_DecodePdu(){
	if(	_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX)
		killTimer(_InactivityTimerId);
	while(!_UseDecoder.testAndSetOrdered(1,0)){}
	_Decoder.setMassive(_Socket.readAll());
	while(_Decoder.getMassive().size()>_Decoder.getMaxMassivePossition()){
		Header _Header;
		_Decoder.setMaxMassivePossition(_Decoder.getMassivePossition()+16);
		if(_Decoder._Header(_Header)){
			_Decoder.setMaxMassivePossition(
				_Decoder.getMassivePossition()+_Header.getCommandLength()-16);
			switch(_Header.getCommandId()){
				case CM_GENERIC_NACK:{
					if(	_State != Closed) {
						GenericNack _GenericNack(_Header);
						if(_Validator._GenericNack(_GenericNack))
							emit onPduError(
							_Validator.getLastError(),_GenericNack);
					}
					break;
				}
				case CM_BIND_TRANSMITTER:
				case CM_BIND_RECEIVER:
				case CM_BIND_TRANSCEIVER:{
					if(	_State == Open || _State == Outbound) {
						Bind _BindBody(_Header);
						if(_Decoder._BindBody(_BindBody))
							if(_Validator._Bind(_BindBody))
								emit onBind(_BindBody);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_BIND_TRANSMITTER_RESP:
				case CM_BIND_RECEIVER_RESP:
				case CM_BIND_TRANSCEIVER_RESP:{		
					if(	_State == Open || _State == Outbound) {
						BindResp _BindRespBody(_Header);
						if(_Decoder._BindRespBody(_BindRespBody))
							if(_Validator._BindResp(_BindRespBody)){
								if(_DelRequest(_Header)){
									switch(_Header.getCommandId()){
										case CM_BIND_TRANSMITTER_RESP:
											_SetState(Bound_TX);
											break;
										case CM_BIND_RECEIVER_RESP:
											_SetState(Bound_RX);
											break;
										case CM_BIND_TRANSCEIVER_RESP:
											_SetState(Bound_TRX);
											break;
									}
									emit onBindResp(_BindRespBody);
								}
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_QUERY_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						QuerySM _QuerySM(_Header);
						if(_Decoder._QuerySMBody(_QuerySM))
							if(_Validator._QuerySM(_QuerySM))
								emit onQuerySM(_QuerySM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_QUERY_SM_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						QuerySMResp _QuerySMResp(_Header);
						if(_Decoder._QuerySMRespBody(_QuerySMResp))
							if(_Validator._QuerySMResp(_QuerySMResp)){
								if(_DelRequest(_Header))
									emit onQuerySMResp(_QuerySMResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_SUBMIT_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						SubmitSM _SubmitSM(_Header);
						if(_Decoder._SubmitSMBody(_SubmitSM))
							if(_Validator._SubmitSM(_SubmitSM))
								emit onSubmitSM(_SubmitSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_SUBMIT_SM_RESP:{	
					if(	_State == Bound_TX || _State == Bound_TRX) {
						SubmitSMResp _SubmitSMResp(_Header);
						if(_Decoder._SubmitSMRespBody(_SubmitSMResp))
							if(_Validator._SubmitSMResp(_SubmitSMResp)){
								if(_DelRequest(_Header))
									emit onSubmitSMResp(_SubmitSMResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_DELIVER_SM:{
					if(	_State == Bound_RX || _State == Bound_TRX) {
						DeliverSM _DeliverSM(_Header);
						if(_Decoder._DeliverSMBody(_DeliverSM))
							if(_Validator._DeliverSM(_DeliverSM))
								emit onDeliverSM(_DeliverSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_DELIVER_SM_RESP:{
					if(	_State == Bound_RX || _State == Bound_TRX) {
						DeliverSMResp _DeliverSMResp(_Header);
						if(_Decoder._DeliverSMRespBody(_DeliverSMResp))
							if(_Validator._DeliverSMResp(_DeliverSMResp)){
								if(_DelRequest(_Header))
									emit onDeliverSMResp(_DeliverSMResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_UNBIND:{
					if(	_State == Bound_TX || 
						_State == Bound_RX ||
						_State == Bound_TRX) {
						Unbind _Unbind(_Header);
						if(_Validator._Unbind(_Unbind)){
							_SetState(Unbound);
							emit onUnbind(_Unbind);
						}else
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				case CM_UNBIND_RESP:{
					if(	_State == Bound_TX || 
						_State == Bound_RX ||
						_State == Bound_TRX) {
						UnbindResp _UnbindResp(_Header);
						if(_Validator._UnbindResp(_UnbindResp)){
							if(_DelRequest(_Header)){
								_SetState(Unbound);
								emit onUnbindResp(_UnbindResp);
							}
						}else
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				case CM_REPLACE_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						ReplaceSM _ReplaceSM(_Header);
						if(_Decoder._ReplaceSMBody(_ReplaceSM))
							if(_Validator._ReplaceSM(_ReplaceSM))
								emit onReplaceSM(_ReplaceSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_REPLACE_SM_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						ReplaceSMResp _ReplaceSMResp(_Header);
						if(_Validator._ReplaceSMResp(_ReplaceSMResp)){
							if(_DelRequest(_Header))
								onReplaceSMResp(_ReplaceSMResp);
						}else
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				case CM_CANCEL_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						CancelSM _CancelSM(_Header);
						if(_Decoder._CancelSMBody(_CancelSM))
							if(_Validator._CancelSM(_CancelSM))
								emit onCancelSM(_CancelSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_CANCEL_SM_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						CancelSMResp _CancelSMResp(_Header);
						if(_Validator._CancelSMResp(_CancelSMResp)){
							if(_DelRequest(_Header))
								onCancelSMResp(_CancelSMResp);
						}else
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				case CM_OUTBIND:{
					if(	_State == Open) {
						Outbind _Outbind(_Header);
						if(_Decoder._OutbindBody(_Outbind))
							if(_Validator._Outbind(_Outbind)){
								_SetState(Outbound);
								emit onOutbind(_Outbind);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_ENQUIRE_LINK:{
					if(	_State != Closed) {
						EnquireLink _EnquireLink(_Header);
						if(_Validator._EnquireLink(_EnquireLink))
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				case CM_ENQUIRE_LINK_RESP:{
					if(	_State != Closed) {
						EnquireLinkResp _EnquireLinkResp(_Header);
						if(_Validator._EnquireLinkResp(_EnquireLinkResp)){
							if(_DelRequest(_Header))
								emit onEnquireLinkResp(_EnquireLinkResp);
						}else
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				case CM_SUBMIT_MULTI:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						SubmitMulti _SubmitMulti(_Header);
						if(_Decoder._SubmitMultiBody(_SubmitMulti))
							if(_Validator._SubmitMulti(_SubmitMulti))
								emit onSubmitMulti(_SubmitMulti);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_SUBMIT_MULTI_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						SubmitMultiResp _SubmitMultiResp(_Header);
						if(_Decoder._SubmitMultiRespBody(_SubmitMultiResp))
							if(_Validator._SubmitMultiResp(_SubmitMultiResp)){
								if(_DelRequest(_Header))
									emit onSubmitMultiResp(_SubmitMultiResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_ALERT_NOTIFICATION:{
					if(	_State == Bound_RX || _State == Bound_TRX) {
						AlertNotification _AlertNotification(_Header);
						if(_Decoder._AlertNotificationBody(_AlertNotification))
							if(_Validator._AlertNotification(_AlertNotification))
								emit onAlertNotification(_AlertNotification);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_DATA_SM:{
					if(	_State == Bound_TX || 
						_State == Bound_RX ||
						_State == Bound_TRX) {
						DataSM _DataSM(_Header);
						if(_Decoder._DataSMBody(_DataSM))
							if(_Validator._DataSM(_DataSM))
								emit onDataSM(_DataSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_DATA_SM_RESP:{
					if(	_State == Bound_TX || 
						_State == Bound_RX ||
						_State == Bound_TRX) {
						DataSMResp _DataSMResp(_Header);
						if(_Decoder._DataSMRespBody(_DataSMResp))
							if(_Validator._DataSMResp(_DataSMResp)){
								if(_DelRequest(_Header))
									emit onDataSMResp(_DataSMResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_BROADCAST_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						BroadcastSM _BroadcastSM(_Header);
						if(_Decoder._BroadcastSMBody(_BroadcastSM))
							if(_Validator._BroadcastSM(_BroadcastSM))
								emit onBroadcastSM(_BroadcastSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_BROADCAST_SM_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						BroadcastSMResp _BroadcastSMResp(_Header);
						if(_Decoder._BroadcastSMRespBody(_BroadcastSMResp))
							if(_Validator._BroadcastSMResp(_BroadcastSMResp)){
								if(_DelRequest(_Header))
									emit onBroadcastSMResp(_BroadcastSMResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_QUERY_BROADCAST_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						QueryBroadcastSM _QueryBroadcastSM(_Header);
						if(_Decoder._QueryBroadcastSMBody(_QueryBroadcastSM))
							if(_Validator._QueryBroadcastSM(_QueryBroadcastSM))
								emit onQueryBroadcastSM(_QueryBroadcastSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_QUERY_BROADCAST_SM_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						QueryBroadcastSMResp _QueryBroadcastSMResp(_Header);
						if(_Decoder._QueryBroadcastSMRespBody(_QueryBroadcastSMResp))
							if(_Validator._QueryBroadcastSMResp(_QueryBroadcastSMResp)){
								if(_DelRequest(_Header))
									emit onQueryBroadcastSMResp(_QueryBroadcastSMResp);
							}else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_CANCEL_BROADCAST_SM:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						CancelBroadcastSM _CancelBroadcastSM(_Header);
						if(_Decoder._CancelBroadcastSMBody(_CancelBroadcastSM))
							if(_Validator._CancelBroadcastSM(_CancelBroadcastSM))	
								emit onCancelBroadcastSM(_CancelBroadcastSM);
							else
								emit onPduError(_Validator.getLastError(),_Header);
						else
							emit onPduError(_Decoder.getLastError(),_Header);
					}
					break;
				}
				case CM_CANCEL_BROADCAST_SM_RESP:{
					if(	_State == Bound_TX || _State == Bound_TRX) {
						CancelBroadcastSMResp _CancelBroadcastSMResp(_Header);
						if(_Validator._CancelBroadcastSMResp(_CancelBroadcastSMResp)){
							if(_DelRequest(_Header))
								emit onCancelBroadcastSMResp(_CancelBroadcastSMResp);
						}else
							emit onPduError(_Validator.getLastError(),_Header);
					}
					break;
				}
				default: {
					emit onPduError(ErrorCode::ESME_RINVCMDID,_Header);
					break;
				}
			}
		}else
			emit onPduError(_Decoder.getLastError(),_Header);
	}
	_Decoder.clearMassive();
	_UseDecoder.fetchAndAddOrdered(1);
	if(	_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX)
		_InactivityTimerId = startTimer(_InactivityTime);
}

void Session::_Bind(const Bind &nBind) {
	if(_State == Open || _State == Outbound) {
		if(_Validator._Bind(nBind)) {
			_AddRequest(new Request(nBind,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._Bind(nBind);
			_SendPdu();	
		}else
			emit onPduError(_Validator.getLastError(),nBind);
	}
}

void Session::_BindResp(const BindResp &nBindResp){
	if(_State == Open || _State == Outbound){
		if(_Validator._BindResp(nBindResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._BindResp(nBindResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nBindResp);
	}
}

void Session::_Outbind(const Outbind &nOutbind){
	if(_State == Open) {
		if(_Validator._Outbind(nOutbind)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._Outbind(nOutbind);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nOutbind);
	}
}

void Session::_Unbind(const Unbind &nUnbind){
	if(_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._Unbind(nUnbind)){
			_AddRequest(new Request(nUnbind,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._Unbind(nUnbind);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nUnbind);
	}
}

void Session::_UnbindResp(const UnbindResp &nUnbindResp){
	if(_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._UnbindResp(nUnbindResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._UnbindResp(nUnbindResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nUnbindResp);
	}
}

void Session::_EnquireLink(const EnquireLink &nEnquireLink){
	if(_State != Closed) {
		if(_Validator._EnquireLink(nEnquireLink)){
			_AddRequest(new Request(nEnquireLink,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._EnquireLink(nEnquireLink);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nEnquireLink);
	}
}

void Session::_EnquireLinkResp(const EnquireLinkResp &nEnquireLinkResp){
	if(_State != Closed) {
		if(_Validator._EnquireLinkResp(nEnquireLinkResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._EnquireLinkResp(nEnquireLinkResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nEnquireLinkResp);
	}
}

void Session::_AlertNotification(
	const AlertNotification &nAlertNotification){
	if(_State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._AlertNotification(nAlertNotification)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._AlertNotification(nAlertNotification);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nAlertNotification);
	}
}

void Session::_GenericNack(const GenericNack &nGenericNack){
	if(_State != Closed) {
		if(_Validator._GenericNack(nGenericNack)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._GenericNack(nGenericNack);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nGenericNack);
	}
}

void Session::_SubmitSM(const SubmitSM &nSubmitSM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._SubmitSM(nSubmitSM)){
			_AddRequest(new Request(nSubmitSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._SubmitSM(nSubmitSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nSubmitSM);
	}
}

void Session::_SubmitSMResp(const SubmitSMResp &nSubmitSMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._SubmitSMResp(nSubmitSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._SubmitSMResp(nSubmitSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nSubmitSMResp);
	}
}

void Session::_DataSM(const DataSM &nDataSM){
	if(_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._DataSM(nDataSM)){
			_AddRequest(new Request(nDataSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._DataSM(nDataSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nDataSM);
	}
}

void Session::_DataSMResp(const DataSMResp &nDataSMResp){
	if(_State == Bound_TX || _State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._DataSMResp(nDataSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._DataSMResp(nDataSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nDataSMResp);
	}
}

void Session::_SubmitMulti(const SubmitMulti &nSubmitMulti){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._SubmitMulti(nSubmitMulti)){
			_AddRequest(new Request(nSubmitMulti,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._SubmitMulti(nSubmitMulti);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nSubmitMulti);
	}
}

void Session::_SubmitMultiResp(const SubmitMultiResp &nSubmitMultiResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._SubmitMultiResp(nSubmitMultiResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._SubmitMultiResp(nSubmitMultiResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nSubmitMultiResp);
	}
}

void Session::_DeliverSM(const DeliverSM &nDeliverSM){
	if(_State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._DeliverSM(nDeliverSM)){
			_AddRequest(new Request(nDeliverSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._DeliverSM(nDeliverSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nDeliverSM);
	}
}

void Session::_DeliverSMResp(const DeliverSMResp &nDeliverSMResp){
	if(_State == Bound_RX || _State == Bound_TRX) {
		if(_Validator._DeliverSMResp(nDeliverSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._DeliverSMResp(nDeliverSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nDeliverSMResp);
	}
}

void Session::_BroadcastSM(const BroadcastSM &nBroadcastSM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._BroadcastSM(nBroadcastSM)){
			_AddRequest(new Request(nBroadcastSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._BroadcastSM(nBroadcastSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nBroadcastSM);
	}
}

void Session::_BroadcastSMResp(const BroadcastSMResp &nBroadcastSMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._BroadcastSMResp(nBroadcastSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._BroadcastSMResp(nBroadcastSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nBroadcastSMResp);
	}
}

void Session::_CancelSM(const CancelSM &nCancelSM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._CancelSM(nCancelSM)){
			_AddRequest(new Request(nCancelSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._CancelSM(nCancelSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nCancelSM);
	}
}

void Session::_CancelSMResp(const CancelSMResp &nCancelSMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._CancelSMResp(nCancelSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._CancelSMResp(nCancelSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nCancelSMResp);
	}
}

void Session::_QuerySM(const QuerySM &nQuerySM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._QuerySM(nQuerySM)){
			_AddRequest(new Request(nQuerySM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._QuerySM(nQuerySM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nQuerySM);
	}
}

void Session::_QuerySMResp(const QuerySMResp &nQuerySMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._QuerySMResp(nQuerySMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._QuerySMResp(nQuerySMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nQuerySMResp);
	}
}

void Session::_ReplaceSM(const ReplaceSM &nReplaceSM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._ReplaceSM(nReplaceSM)){
			_AddRequest(new Request(nReplaceSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._ReplaceSM(nReplaceSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nReplaceSM);
	}
}

void Session::_ReplaceSMResp(const ReplaceSMResp &nReplaceSMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._ReplaceSMResp(nReplaceSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._ReplaceSMResp(nReplaceSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nReplaceSMResp);
	}
}

void Session::_QueryBroadcastSM(const QueryBroadcastSM &nQueryBroadcastSM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._QueryBroadcastSM(nQueryBroadcastSM)){
			_AddRequest(new Request(nQueryBroadcastSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._QueryBroadcastSM(nQueryBroadcastSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nQueryBroadcastSM);
	}
}

void Session::_QueryBroadcastSMResp(
	const QueryBroadcastSMResp &nQueryBroadcastSMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._QueryBroadcastSMResp(nQueryBroadcastSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._QueryBroadcastSMResp(nQueryBroadcastSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nQueryBroadcastSMResp);
	}
}

void Session::_CancelBroadcastSM(const CancelBroadcastSM &nCancelBroadcastSM){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._CancelBroadcastSM(nCancelBroadcastSM)){
			_AddRequest(new Request(nCancelBroadcastSM,_ResponseTime));
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._CancelBroadcastSM(nCancelBroadcastSM);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nCancelBroadcastSM);
	}
}

void Session::_CancelBroadcastSMResp(
	const CancelBroadcastSMResp &nCancelBroadcastSMResp){
	if(_State == Bound_TX || _State == Bound_TRX) {
		if(_Validator._CancelBroadcastSMResp(nCancelBroadcastSMResp)){
			while(!_UseEncoder.testAndSetOrdered(1,0)){}
			_Encoder._CancelBroadcastSMResp(nCancelBroadcastSMResp);
			_SendPdu();
		}else
			emit onPduError(_Validator.getLastError(),nCancelBroadcastSMResp);
	}
}

void Session::timerEvent(QTimerEvent *nEvent){
	if(nEvent->timerId() == _SessionInitTimerId)
		emit onSessionInitTimerTimeout();
	if(nEvent->timerId() == _EnquireLinkTimerId)
		emit onEnquireLinkTimerTimeout();
	if(nEvent->timerId() == _InactivityTimerId)
		emit onInactivityTimerTimeout();
}

void Session::_SetState(const State nState){
	switch(nState){
		case Open:
		case Outbound:
			_SessionInitTimerId = startTimer(_SessionInitTime);
			_EnquireLinkTimerId = startTimer(_EnquireLinkTime);
			break;
		case Bound_TX:
		case Bound_RX:
		case Bound_TRX:
			killTimer(_SessionInitTimerId);
			_InactivityTimerId = startTimer(_InactivityTime);
			break;
		case Unbound:
			_InactivityTimerId = startTimer(_InactivityTime);
			break;
		case Closed:
			killTimer(_SessionInitTimerId);	
			killTimer(_EnquireLinkTimerId);
			killTimer(_InactivityTimerId);
			break;
	}
	_State = nState;
}

void Session::_OpenResp(){
	_SetState(Open);
	emit onOpen();
}

void Session::_CloseResp(){
	_SetState(Closed);
	emit onClose();
}

void Session::_RequestTimeout(const Bind &nBind){
	if(_DelRequest(nBind))
		emit onBindTimeout(nBind);
}

void Session::_RequestTimeout(const Unbind &nUnbind){
	if(_DelRequest(nUnbind))
		emit onUnbindTimeout(nUnbind);
}

void Session::_RequestTimeout(const EnquireLink &nEnquireLink){
	if(_DelRequest(nEnquireLink))
		emit onEnquireLinkTimeout(nEnquireLink);
}

void Session::_RequestTimeout(const SubmitSM &nSubmitSM){
	if(_DelRequest(nSubmitSM))
		emit onSubmitSMTimeout(nSubmitSM);
}

void Session::_RequestTimeout(const DataSM &nDataSM){
	if(_DelRequest(nDataSM))
		emit onDataSMTimeout(nDataSM);
}

void Session::_RequestTimeout(const SubmitMulti &nSubmitMulti){
	if(_DelRequest(nSubmitMulti))
		emit onSubmitMultiTimeout(nSubmitMulti);
}

void Session::_RequestTimeout(const DeliverSM &nDeliverSM){
	if(_DelRequest(nDeliverSM))
		emit onDeliverSMTimeout(nDeliverSM);
}

void Session::_RequestTimeout(const BroadcastSM &nBroadcastSM){
	if(_DelRequest(nBroadcastSM))
		emit onBroadcastSMTimeout(nBroadcastSM);
}

void Session::_RequestTimeout(const CancelSM &nCancelSM){
	if(_DelRequest(nCancelSM))
		emit onCancelSMTimeout(nCancelSM);
}

void Session::_RequestTimeout(const QuerySM &nQuerySM){
	if(_DelRequest(nQuerySM))
		emit onQuerySMTimeout(nQuerySM);
}

void Session::_RequestTimeout(const ReplaceSM &nReplaceSM){
	if(_DelRequest(nReplaceSM))
		emit onReplaceSMTimeout(nReplaceSM);
}

void Session::_RequestTimeout(const QueryBroadcastSM &nQueryBroadcastSM){
	if(_DelRequest(nQueryBroadcastSM))
		emit onQueryBroadcastSMTimeout(nQueryBroadcastSM);
}

void Session::_RequestTimeout(const CancelBroadcastSM &nCancelBroadcastSM){
	if(_DelRequest(nCancelBroadcastSM))
		emit onCancelBroadcastSMTimeout(nCancelBroadcastSM);
}

void Session::_SocketError(QAbstractSocket::SocketError _sockError){
	if(_Socket.state() == QTcpSocket::ConnectedState){
		_Socket.close();
		_Socket.disconnectFromHost();
	}else
		_SetState(Closed);
	emit onSocketError(_sockError);
}

void Session::_AddRequest(Request *nRequest){
	connect(nRequest, SIGNAL(onBindTransmitterTimeout(const Bind &)), 
		SLOT(_RequestTimeout(const Bind &)));
	connect(nRequest, SIGNAL(onBindReceiverTimeout(const Bind &)), 
		SLOT(_RequestTimeout(const Bind &)));
	connect(nRequest, SIGNAL(onBindTransceiverTimeout(const Bind &)), 
		SLOT(_RequestTimeout(const Bind &)));
	connect(nRequest, SIGNAL(onUnbindTimeout(const Unbind &)), 
		SLOT(_RequestTimeout(const Unbind &)));
	connect(nRequest, SIGNAL(onEnquireLinkTimeout(const EnquireLink &)), 
		SLOT(_RequestTimeout(const EnquireLink &)));
	connect(nRequest, SIGNAL(onSubmitSMTimeout(const SubmitSM &)), 
		SLOT(_RequestTimeout(const SubmitSM &)));
	connect(nRequest, SIGNAL(onDataSMTimeout(const DataSM &)), 
		SLOT(_RequestTimeout(const DataSM &)));
	connect(nRequest, SIGNAL(onSubmitMultiTimeout(const SubmitMulti &)), 
		SLOT(_RequestTimeout(const SubmitMulti &)));
	connect(nRequest, SIGNAL(onDeliverSMTimeout(const DeliverSM &)), 
		SLOT(_RequestTimeout(const DeliverSM &)));
	connect(nRequest, SIGNAL(onBroadcastSMTimeout(const BroadcastSM &)), 
		SLOT(_RequestTimeout(const BroadcastSM &)));
	connect(nRequest, SIGNAL(onCancelSMTimeout(const CancelSM &)), 
		SLOT(_RequestTimeout(const CancelSM &)));
	connect(nRequest, SIGNAL(onQuerySMTimeout(const QuerySM &)), 
		SLOT(_RequestTimeout(const QuerySM &)));
	connect(nRequest, SIGNAL(onReplaceSMTimeout(const ReplaceSM &)), 
		SLOT(_RequestTimeout(const ReplaceSM &)));
	connect(nRequest, SIGNAL(onQueryBroadcastSMTimeout(const QueryBroadcastSM &)), 
		SLOT(_RequestTimeout(const QueryBroadcastSM &)));
	connect(nRequest, SIGNAL(onCancelBroadcastSMTimeout(const CancelBroadcastSM &)), 
		SLOT(_RequestTimeout(const CancelBroadcastSM &)));
	while(!_UseRequestList.testAndSetOrdered(1,0)){}
	_RequestList.push_back(nRequest);
	_UseRequestList.fetchAndAddOrdered(1);
}

bool Session::_DelRequest(const Header &nHeader){
	while(!_UseRequestList.testAndSetOrdered(1,0)){}
	for(int i=0;i<_RequestList.size();i++){
		Request *_Request(_RequestList[i]);
		if(*_Request == nHeader) {
			_RequestList.removeAt(i);
			_UseRequestList.fetchAndAddOrdered(1);
			_Request->blockSignals(true);
			disconnect(_Request, 
				SIGNAL(onBindTransmitterTimeout(const Bind &)));
			disconnect(_Request, 
				SIGNAL(onBindReceiverTimeout(const Bind &)));
			disconnect(_Request, 
				SIGNAL(onBindTransceiverTimeout(const Bind &)));
			disconnect(_Request, 
				SIGNAL(onUnbindTimeout(const Unbind &)));
			disconnect(_Request, 
				SIGNAL(onEnquireLinkTimeout(const EnquireLink &)));
			disconnect(_Request, 
				SIGNAL(onSubmitSMTimeout(const SubmitSM &)));
			disconnect(_Request, 
				SIGNAL(onDataSMTimeout(const DataSM &)));
			disconnect(_Request, 
				SIGNAL(onSubmitMultiTimeout(const SubmitMulti &)));
			disconnect(_Request, 
				SIGNAL(onDeliverSMTimeout(const DeliverSM &)));
			disconnect(_Request, 
				SIGNAL(onBroadcastSMTimeout(const BroadcastSM &)));
			disconnect(_Request, 
				SIGNAL(onCancelSMTimeout(const CancelSM &)));
			disconnect(_Request, 
				SIGNAL(onQuerySMTimeout(const QuerySM &)));
			disconnect(_Request, 
				SIGNAL(onReplaceSMTimeout(const ReplaceSM &)));
			disconnect(_Request, 
				SIGNAL(onQueryBroadcastSMTimeout(const QueryBroadcastSM &)));
			disconnect(_Request, 
				SIGNAL(onCancelBroadcastSMTimeout(const CancelBroadcastSM &)));
			_Request->deleteLater();
			return true;
		}
	}
	_UseRequestList.fetchAndAddOrdered(1);
	return false;
}
